using System;
using Microsoft.SPOT;
using WebServer;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using SDCard;

//using NetMf.CommonExtensions;

public class UploadPage //  /Upload Form
{
        
    public string DoUploadPage(BaseRequest request, SDCard.SDCard sdCard)
    {
        string line6 = @"<form method=""POST"" enctype=""multipart/form-data"" action=""/Uploadpage"">
<input type=submit value=Press> to upload the file!<br>
path: <input type=""text"" name=""path""><br>
File to upload: <input type=""file"" name=""upfile""><br>
<br>

</form>";

        string line7 = "";
        string line8 = "";
        Hashtable formVariables = new Hashtable();
        if (request.HttpRequestType == EnumRequestType.Post)
        {

            PostRequest postRequest = (PostRequest)request;//same object just to save casting everywhere.
            // This form should be short so get it all data now, in one go.
            // assume no content sent with first packet todo fix
            int contentLengthFromHeader = int.Parse(postRequest.HeaderFields["Content-Length"].ToString());
            int contentLengthReceived = 0;
            string requestContent = "";
            string fileName = "";
            string boundaryPattern = "";
            string fileDirectoryPath = SDCard.SDCard.MountDirectoryPath + "\\";
            {
                if (contentLengthReceived < contentLengthFromHeader)// get next packet, this should have the start of any file in it. // todo put timeout
                {
                    int count = 0;
                    byte[] data = postRequest.GetMoreBytesHandler(postRequest.ConnectionSocket, out count);
                    contentLengthReceived += count;
//                    System.Text.Encoding enc = System.Text.Encoding.ASCII;
//                    string myString = enc.GetString(myByteArray);
//                    requestContent += Convert.FromBase64CharArray(data, 0, data.Length);//todo if base64 encoded

                    requestContent += new string(Encoding.UTF8.GetChars(data)); 

                }
                string boundary = postRequest.HeaderFields["boundary"].ToString();
                //                int nextBoundaryIndex = requestContent.IndexOf(boundary);// todo boundaries can change
                boundaryPattern = "--" + boundary;//"#\n\n(.*)\n--$boundary#"
                Regex MyRegex = new Regex(boundaryPattern, RegexOptions.Multiline);
                string[] split = MyRegex.Split(requestContent);
                for (int i = 0; i < split.Length; i++)
                {
                    const string _ContentDispositionSearch = "Content-Disposition: form-data; name=\"";
                    int pos = split[i].IndexOf(_ContentDispositionSearch);
                    if (pos >= 0)
                    {
                        string remainder = split[i].Substring(pos + _ContentDispositionSearch.Length);
                        //                        ConsoleWrite.Print(remainder);
                        string[] nameSplit = remainder.Split(new char[] { '\"' }, 2);
                        string name = nameSplit[0];
                        if (nameSplit[1][0] == ';')
                        {// file
                            int fileDataSeparatorIndex = nameSplit[1].IndexOf("\r\n\r\n"); // "\r\n\r\n" data starts after double new line
                            if (fileDataSeparatorIndex >= 0)
                            {
                                string fileNameSection = nameSplit[1].Substring(0, fileDataSeparatorIndex);
                                string[] fileNameSplit = fileNameSection.Split(new char[] { '\"' });
                                formVariables.Add("fileName", fileNameSplit[1]);
                                fileName = fileNameSplit[1];
                                string fileDataPart1 = nameSplit[1].Substring(fileDataSeparatorIndex + 4);
                                sdCard.Write(fileDirectoryPath, fileName, System.IO.FileMode.Create, fileDataPart1);
                            }
                        }
                        else
                        {// normal form variable
                            StringBuilder value = new StringBuilder(nameSplit[1]);
                            value = value.Replace("\r", "").Replace("\n", "").Replace("/", "\\");
                            if (nameSplit[0] == "path")
                            {
                                fileDirectoryPath = SDCard.SDCard.MountDirectoryPath + "\\" + value + "\\";
                            }
                            formVariables.Add(nameSplit[0], value);


                        }
                    }

                }
            }

            // get the rest of the file and send to sd card
            if (fileName.Length > 0)// todo what other checks
            {
                while (contentLengthReceived < contentLengthFromHeader)// get next packet, this should have the start of any file in it. // todo put timeout
                {
                    byte[] data = null;
                    int count = 0;
                    {
                        data = postRequest.GetMoreBytesHandler(postRequest.ConnectionSocket, out count);
                        contentLengthReceived += count;
                        requestContent = new string(Encoding.UTF8.GetChars(data, 0, count));
                    }
                    ConsoleWrite.CollectMemoryAndPrint(true, Thread.CurrentThread.ManagedThreadId);
                    int boundaryPosition = requestContent.IndexOf(boundaryPattern);
                    if (boundaryPosition < 0)
                    {// no boundary so write all the bytes
                        sdCard.Write(fileDirectoryPath, fileName, System.IO.FileMode.Append, data, count);
                    }
                    else
                    {//  boundary so write some of the bytes via a string
                        string fileContent = requestContent.Substring(0, boundaryPosition);
                        sdCard.Write(fileDirectoryPath, fileName, System.IO.FileMode.Append, fileContent);
                    }
                    // todo other params following

                }
            }

        }
        foreach (string key in formVariables.Keys)
        {
            line7 += "<p>" + key + ": " + formVariables[key].ToString() + "</p>";
        }

        string content = HtmlGeneral.HtmlStart + line6 + line7 + line8 + HtmlGeneral.HtmlEnd;
        string header = HttpGeneral.GetHttpHeader(content.Length, "text/html", 1);
        return header + content;
    }





}
